/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * KeyPanel.java
 *
 * Created on 2012/02/05, 1:04:02
 */
package sweetvsti.gui;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.File;
import java.util.ArrayList;
import javax.swing.JLayeredPane;
import sweetvsti.Settings;
import sweetvsti.TestWave;

/**
 *
 * @author uimac
 */
public class KeyPanel extends javax.swing.JPanel implements ComponentListener {

    private static class KeyButton extends javax.swing.JPanel implements ComponentListener, MouseListener {

        private int noteNumber = 0;
        TestWave test = new TestWave();
        private boolean isBlack = false;
        private boolean isValid = false;
        private Color whiteMouseOverColor = new Color(240, 240, 240);
        private Color blackMouseOverColor = new Color(100, 100, 100);
        private Color lineColor = new Color(50, 50, 50);
        private Color invalidWhiteColor = new Color(150, 150, 150);
        private Color invalidBlackColor = new Color(100, 100, 100);

        public KeyButton(int noteNumber, boolean isBlack) {
            this.noteNumber = noteNumber;
            this.isBlack = isBlack;

            this.addComponentListener(this);
            this.addMouseListener(this);

            this.setIsValid(false);
        }

        protected void paintComponent(Graphics g) {
            super.paintComponent(g);

            Graphics2D g2d = (Graphics2D) g;
            if (g2d == null) {
                return;
            }

            g2d.setColor(this.getLineColor());
            g2d.drawRect(0, 0, getWidth(), getHeight());
        }
        //    コンポーネントが不可視になると呼び出されます

        public void componentHidden(ComponentEvent e) {
        }
        //      コンポーネントの位置が変わると呼び出されます。

        public void componentMoved(ComponentEvent e) {
        }
        //        コンポーネントのサイズが変わると呼び出されます。

        public void componentResized(ComponentEvent e) {
        }
        //        コンポーネントが可視になると呼び出されます。

        public void componentShown(ComponentEvent e) {
        }
        //  コンポーネント上でマウスボタンをクリック (押してから離す) したときに呼び出されます。

        public void mouseClicked(MouseEvent e) {
        }
        // コンポーネントにマウスが入ると呼び出されます。

        public void mouseEntered(MouseEvent e) {
            if (this.isValid) {
                if (isBlack) {
                    super.setBackground(this.getBlackMouseOverColor());
                } else {
                    super.setBackground(this.getWhiteMouseOverColor());
                }
            }
        }
        // コンポーネントからマウスが出ると呼び出されます。

        public void mouseExited(MouseEvent e) {
            if (this.isValid) {
                if (isBlack) {
                    super.setBackground(Color.black);
                } else {
                    super.setBackground(Color.white);
                }
            }
        }
        //  コンポーネント上でマウスボタンが押されると呼び出されます。

        public void mousePressed(MouseEvent e) {
            test.noteOn(this.noteNumber);
        }
        //  コンポーネント上でマウスボタンが離されると呼び出されます。

        public void mouseReleased(MouseEvent e) {
        }

        /**
         * @return the whiteMouseOverColor
         */
        public Color getWhiteMouseOverColor() {
            return whiteMouseOverColor;
        }

        /**
         * @return the blackMouseOverColor
         */
        public Color getBlackMouseOverColor() {
            return blackMouseOverColor;
        }

        /**
         * @return the lineColor
         */
        public Color getLineColor() {
            return lineColor;
        }

        /**
         * @return the isValid
         */
        public boolean isIsValid() {
            return isValid;
        }

        /**
         * @param isValid the isValid to set
         */
        public void setIsValid(boolean isValid) {
            this.isValid = isValid;
            if (isValid) {
                if (isBlack) {
                    this.setBackground(Color.black);
                } else {
                    this.setBackground(Color.white);
                }
            } else {
                if (isBlack) {
                    this.setBackground(this.getInvalidBlackColor());
                } else {
                    this.setBackground(this.getInvalidWhiteColor());
                }
            }
        }

        /**
         * @return the invalidWhiteColor
         */
        public Color getInvalidWhiteColor() {
            return invalidWhiteColor;
        }

        /**
         * @return the invalidBlackColor
         */
        public Color getInvalidBlackColor() {
            return invalidBlackColor;
        }
    }
    
    private ArrayList<KeyButton> keyList = new ArrayList<KeyButton>();

    /** Creates new form KeyPanel */
    public KeyPanel() {
        initComponents();
        addComponentListener(this);

        JLayeredPane layeredPane = new JLayeredPane();
        layeredPane.setPreferredSize(new Dimension(30 * 70, 100));

        int preX = 0;
        int preButtonWidth = 0;
        int noteNumber = 0;
        for (int i = 0; i < 70; ++i) {
            int key = (i % 7);
            if (key != 0 && key != 3) {
                KeyButton black = new KeyButton(noteNumber++, true);
                layeredPane.add(black, new Integer(10));
                keyList.add(black);

                black.setPreferredSize(new Dimension(20, 50));
                black.setBounds(preX + 20, 0, 20, 50);
            }

            KeyButton white = new KeyButton(noteNumber++, false);
            layeredPane.add(white, new Integer(5));
            keyList.add(white);

            white.setPreferredSize(new Dimension(30, 100));
            white.setBounds(preX + preButtonWidth, 0, 30, 100);


            preX = preX + preButtonWidth;
            preButtonWidth = 30;
        }

        this.add(layeredPane);
    }
    
    /**
     * KeyButtonの有効・無効状態をリセットする
     */
    public void reset()
    {
        // 60がC3で、12個で1オクターブ
        int base_keyboard = 0;
        int keyboards = Settings.instance().getKEYBOARDS();
        int charactors = Settings.instance().getCHARACTERS();
        for (int i = 0; i < keyboards; ++i) {
            for (int k = 0; k < charactors; ++k) {
                int noteNumber = i + base_keyboard;
                String file_name = "480_" + noteNumber + "_" + (k+1) + ".wav";
                File file = new File(Settings.instance().getWaveBaseDir() + File.separator + file_name);
                
                if (k == 0)
                {
                    boolean isValid = (file != null && file.exists() && file.isFile());
                    if (noteNumber >= 0 && noteNumber < this.keyList.size())
                    {
                        KeyButton button = this.keyList.get(noteNumber);
                        button.setIsValid(isValid);
                    }
                }
            }
        }
    }
    

    //    コンポーネントが不可視になると呼び出されます

    public void componentHidden(ComponentEvent e) {
    }
    //      コンポーネントの位置が変わると呼び出されます。

    public void componentMoved(ComponentEvent e) {
    }
    //        コンポーネントのサイズが変わると呼び出されます。

    public void componentResized(ComponentEvent e) {
    }
    //        コンポーネントが可視になると呼び出されます。

    public void componentShown(ComponentEvent e) {
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        setLayout(new javax.swing.BoxLayout(this, javax.swing.BoxLayout.LINE_AXIS));
    }// </editor-fold>//GEN-END:initComponents
    // Variables declaration - do not modify//GEN-BEGIN:variables
    // End of variables declaration//GEN-END:variables
}
